from pml import PML
from pml import Objects
import os

class System(Objects.object.typeobject):
    def __init__(self):
        super().__init__('System')

    def getObject(self):
        self.staticMethods['Shell'] = self.Shell().getObject()

        return self

    @staticmethod
    class Shell(Objects.object.typeobject):
        def __init__(self):
            super().__init__('Shell')

        def getObject(self):
            self.staticMethods['Out'] = self.Out().getObject()
            self.staticMethods['In'] = self.In().getObject()
            self.staticMethods['Command'] = self.Command().getObject()

            return self

        @staticmethod
        class Out(Objects.object.typeobject):
            def __init__(self):
                super().__init__('Out')

            def getObject(self):
                self.staticMethods['print'] = self.print
                self.staticMethods['println'] = self.println
                self.staticMethods['printf'] = self.printf

                return self

            @staticmethod
            def print(frame, this, position, text=''):
                frame.stdio.write(frame, frame.stdio, position, text)

            @staticmethod
            def println(frame, this, position, text=''):
                frame.stdio.write(frame, frame.stdio, position, text)
                frame.stdio.write(frame, frame.stdio, position, '\n')

            @staticmethod
            def printf(frame, this, position, text='', *args):
                frame.stdio.write(frame, frame.stdio, position, (text if isinstance(text, str) else text.obj.value) % tuple([arg.obj.value for arg in args]))

        @staticmethod
        class In(Objects.object.typeobject):
            def __init__(self):
                super().__init__('In')

            def getObject(self):
                self.staticMethods['gets'] = self.gets
                self.staticMethods['input'] = self.input

                return self

            @staticmethod
            def gets(frame, this, position):
                return frame.stdio.get(frame, frame.stdio, position)

            @staticmethod
            def input(frame, this, position, text=''):
                return frame.stdio.get(frame, frame.stdio, position, text if isinstance(text, str) else text.obj.value)

        @staticmethod
        class Command(Objects.object.typeobject):
            def __init__(self):
                super().__init__('Command')

            def getObject(self):
                self.staticMethods['run'] = self.run

                return self

            @staticmethod
            def run(frame, this, position, command):
                os.system(command.obj.value)

    @staticmethod
    class File(Objects.object.typeobject):
        def __init__(self):
            super().__init__('File')

        def getObject(self):
            return self

        @staticmethod
        def open(frame, this: 'System.File', position, file, mod='r'):
            if mod == 'r':
                return PML.object.PML_RealizePMLObject(this.PMLFileReadStream)

        @staticmethod
        class PMLFileReadStream(Objects.object.typeobject):
            def __init__(self):
                super().__init__('FileReadStream')

            def getObject(self):
                return self

PML_MODULE = PML.module.ModuleSetup(variablesOrFunctions={
    'System': System().getObject()
}, constants={})
